home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / xwin.c < prev    next >
C/C++ Source or Header  |  1998-01-20  |  39KB  |  1,456 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * X interface
  5.   *
  6.   * Copyright 1995, 1996 Bernd Schmidt
  7.   * Copyright 1996 Ed Hanway, Andre Beck, Samuel Devulder, Bruno Coste
  8.   * DGA support by Kai Kollmorgen
  9.   */
  10.  
  11. #include "sysconfig.h"
  12. #include "sysdeps.h"
  13.  
  14. #include <X11/Xlib.h>
  15. #include <X11/Xutil.h>
  16. #include <X11/keysym.h>
  17. #include <X11/cursorfont.h>
  18.  
  19. #include <ctype.h>
  20. #include <signal.h>
  21.  
  22. #include "config.h"
  23. #include "options.h"
  24. #include "threaddep/penguin.h"
  25. #include "uae.h"
  26. #include "memory.h"
  27. #include "custom.h"
  28. #include "readcpu.h"
  29. #include "newcpu.h"
  30. #include "xwin.h"
  31. #include "keyboard.h"
  32. #include "keybuf.h"
  33. #include "gui.h"
  34. #include "debug.h"
  35. #include "picasso96.h"
  36.  
  37. #ifdef USE_DGA_EXTENSION
  38.  
  39. #ifdef USE_VIDMODE_EXTENSION
  40. #include <X11/extensions/xf86vmode.h>
  41. #define VidMode_MINMAJOR 0
  42. #define VidMode_MINMINOR 0
  43. #endif
  44.  
  45. #include <X11/extensions/xf86dga.h>
  46. #define DGA_MINMAJOR 0
  47. #define DGA_MINMINOR 0
  48.  
  49. #elif SHM_SUPPORT_LINKS == 1
  50.  
  51. #include <sys/ipc.h>
  52. #include <sys/shm.h>
  53. #include <X11/extensions/XShm.h>
  54.  
  55. #define DO_PUTIMAGE(IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT) \
  56.     do { \
  57.     if (currprefs.use_mitshm) \
  58.          XShmPutImage (display, mywin, blackgc, IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT, 0); \
  59.     else \
  60.         XPutImage (display, mywin, blackgc, IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT); \
  61.     } while (0)
  62. #else
  63. #define DO_PUTIMAGE(IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT) \
  64.     XPutImage (display, mywin, blackgc, IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT)
  65. #endif
  66.  
  67. #ifdef __cplusplus
  68. static RETSIGTYPE sigbrkhandler(...)
  69. #else
  70. static RETSIGTYPE sigbrkhandler(int foo)
  71. #endif
  72. {
  73.     activate_debugger();
  74.  
  75. #if !defined(__unix) || defined(__NeXT__)
  76.     signal(SIGINT, sigbrkhandler);
  77. #endif
  78. }
  79.  
  80. void setup_brkhandler(void)
  81. {
  82. #if defined(__unix) && !defined(__NeXT__)
  83.     struct sigaction sa;
  84.     sa.sa_handler = sigbrkhandler;
  85.     sa.sa_flags = 0;
  86. #ifdef SA_RESTART
  87.     sa.sa_flags = SA_RESTART;
  88. #endif
  89.     sigemptyset(&sa.sa_mask);
  90.     sigaction(SIGINT, &sa, NULL);
  91. #else
  92.     signal(SIGINT, sigbrkhandler);
  93. #endif
  94. }
  95.  
  96. static Display *display;
  97. static int screen;
  98. static Window rootwin, mywin;
  99.  
  100. static GC whitegc,blackgc,picassogc;
  101. static XColor black,white;
  102. static Colormap cmap;
  103.  
  104. static int need_dither;
  105.  
  106. static int screen_is_picasso;
  107. static char picasso_invalid_lines[1201];
  108.  
  109. static int autorepeatoff = 0;
  110. static char *image_mem;
  111. static XImage *img, *picasso_img;
  112. static Visual *vis;
  113. static XVisualInfo visualInfo;
  114. static int bitdepth, bit_unit;
  115. static Cursor blankCursor, xhairCursor;
  116. static int cursorOn;
  117. static int inverse_byte_order = 0;
  118.  
  119. static int current_width, current_height;
  120.  
  121. static int x11_init_ok;
  122.  
  123.  /* Keyboard and mouse */
  124.  
  125. static int keystate[256];
  126.  
  127. static int inwindow;
  128. const long int eventmask = (KeyPressMask|KeyReleaseMask|ButtonPressMask
  129.                 |ButtonReleaseMask|PointerMotionMask
  130. #ifndef USE_DGA_EXTENSION
  131.                 |FocusChangeMask|EnterWindowMask
  132.                 |ExposureMask
  133.                 |LeaveWindowMask
  134. #endif
  135.                 );
  136.  
  137. static XImage *get_image (int w, int h)
  138. {
  139.     XImage *new_img;
  140. #if SHM_SUPPORT_LINKS == 1
  141.     if (currprefs.use_mitshm) {
  142.     XShmSegmentInfo *shminfo = xmalloc (sizeof(XShmSegmentInfo));
  143.  
  144.     printf("Using MIT-SHM extension.\n");
  145.     new_img = XShmCreateImage(display, vis, bitdepth, ZPixmap, 0, shminfo, w, h);
  146.  
  147.     shminfo->shmid = shmget(IPC_PRIVATE, h * new_img->bytes_per_line,
  148.                    IPC_CREAT | 0777);
  149.     shminfo->shmaddr = new_img->data = image_mem = (char *)shmat(shminfo->shmid, 0, 0);
  150.     shminfo->readOnly = False;
  151.     /* let the xserver attach */
  152.     XShmAttach(display, shminfo);
  153.     XSync(display,0);
  154.     /* now deleting means making it temporary */
  155.     shmctl(shminfo->shmid, IPC_RMID, 0);
  156.     return new_img;
  157.     }
  158. #endif
  159.  
  160.     /* Question for people who know about X: Could we allocate the buffer
  161.      * after creating the image and then do new_img->data = buffer, as above in
  162.      * the SHM case?
  163.      */
  164.     printf("Using normal image buffer.\n");
  165.     image_mem = (char *)xmalloc(h * w * ((bit_unit + 7) / 8)); /* ??? */
  166.     new_img = XCreateImage(display, vis, bitdepth, ZPixmap, 0, image_mem,
  167.                w, h, 32, 0);
  168.     if (new_img->bytes_per_line != w * ((bit_unit + 7) / 8))
  169.     fprintf (stderr, "Possible bug here... graphics may look strange.\n");
  170.  
  171.     return new_img;
  172. }
  173.  
  174. #ifdef USE_DGA_EXTENSION
  175.  
  176. static int fb_bank, fb_banks, fb_mem;
  177. static char *fb_addr;
  178. static int fb_width;
  179.  
  180. #ifdef USE_VIDMODE_EXTENSION
  181. static XF86VidModeModeInfo **allmodes;
  182. static int vidmodecount;
  183.  
  184. static int get_vidmodes (void)
  185. {
  186.     return XF86VidModeGetAllModeLines (display, screen, &vidmodecount, &allmodes);
  187. }
  188.  
  189. static void switch_to_best_mode (void)
  190. {
  191.     int i, best;
  192.     best = 0;
  193.     for (i = 1; i < vidmodecount; i++) {
  194.     if (allmodes[i]->hdisplay >= current_width
  195.         && allmodes[i]->vdisplay >= current_height
  196.         && allmodes[i]->hdisplay <= allmodes[best]->hdisplay
  197.         && allmodes[i]->vdisplay <= allmodes[best]->vdisplay)
  198.         best = i;
  199.     }
  200.     printf ("entering DGA mode: %dx%d (%d, %d)\n",
  201.         allmodes[best]->hdisplay, allmodes[best]->vdisplay,
  202.         current_width, current_height);
  203.     XF86VidModeSwitchToMode (display, screen, allmodes[best]);
  204.     XF86VidModeSetViewPort (display, screen, 0, 0);
  205.     XF86DGADirectVideo(display, screen, XF86DGADirectGraphics | XF86DGADirectMouse | XF86DGADirectKeyb);
  206.     XF86DGASetViewPort (display, screen, 0, 0);
  207.  
  208.     memset (fb_addr, 0, fb_mem * 1024);
  209. }
  210. #endif
  211.  
  212. static void enter_dga_mode (void)
  213. {
  214.     Screen *scr = ScreenOfDisplay (display, screen);
  215.     int w = WidthOfScreen (scr);
  216.     int h = HeightOfScreen (scr);
  217.  
  218.     XRaiseWindow (display, mywin);
  219.  
  220.     /* We want all the key presses */
  221.     XGrabKeyboard (display, rootwin, 1, GrabModeAsync,
  222.            GrabModeAsync,  CurrentTime);
  223.  
  224.     /* and all the mouse moves */
  225.     XGrabPointer (display, rootwin, 1, PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
  226.           GrabModeAsync, GrabModeAsync, None,  None, CurrentTime);
  227.  
  228.     XF86DGAGetVideo (display, screen, &fb_addr, &fb_width, &fb_bank, &fb_mem);
  229.     fprintf (stderr, "addr:%X, width %d, bank size %d mem size %d\n",
  230.          fb_addr, fb_width, fb_bank,fb_mem);
  231.  
  232.     if (fb_bank < fb_mem)
  233.     fprintf (stderr, "banksize < memsize, must use XF86DGASetVidPage !\n");
  234.  
  235.     switch_to_best_mode ();
  236.  
  237.     gfxvidinfo.rowbytes = fb_width*gfxvidinfo.pixbytes;
  238.     gfxvidinfo.bufmem = fb_addr;
  239. }
  240.  
  241. static void leave_dga_mode (void)
  242. {
  243. #ifdef USE_VIDMODE_EXTENSION
  244.     XF86VidModeSwitchToMode (display, screen, allmodes[0]);
  245. #endif
  246.     XF86DGADirectVideo (display, screen, 0);
  247.     XUngrabPointer (display, CurrentTime);
  248.     XUngrabKeyboard (display, CurrentTime);
  249. }
  250.  
  251. #endif
  252. static char *oldpixbuf;
  253.  
  254. void flush_line(int y)
  255. {
  256. #ifdef USE_DGA_EXTENSION
  257.     if (need_dither) {
  258.     char *addr = gfxvidinfo.linemem;
  259.     if (addr == NULL)
  260.         addr = y*gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
  261.  
  262.     DitherLine((unsigned char *)(fb_addr + fb_width*y), (uae_u16 *)addr, 0, y,
  263.            gfxvidinfo.width, bit_unit);
  264.     }
  265. #else
  266.     char *linebuf;
  267.     int xs = 0, xe;
  268.     int len;
  269.  
  270.     linebuf = gfxvidinfo.linemem;
  271.     if (linebuf == NULL)
  272.     linebuf = y*gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
  273.  
  274.     xe = gfxvidinfo.width-1;
  275.  
  276.     if (currprefs.use_low_bandwidth) {
  277.     char *src, *dst;
  278.     switch(gfxvidinfo.pixbytes) {
  279.      case 4:
  280.         {
  281.         uae_u32 *newp = (uae_u32 *)linebuf;
  282.         uae_u32 *oldp = (uae_u32 *)((uae_u8 *)image_mem + y*img->bytes_per_line);
  283.         while (newp[xs] == oldp[xs]) {
  284.             if (xs == xe)
  285.             return;
  286.             xs++;
  287.         }
  288.         while (newp[xe] == oldp[xe]) xe--;
  289.  
  290.         dst = (char *)(oldp + xs); src = (char *)(newp + xs);
  291.         }
  292.         break;
  293.      case 2:
  294.         {
  295.         uae_u16 *newp = (uae_u16 *)linebuf;
  296.         uae_u16 *oldp = (uae_u16 *)((uae_u8 *)image_mem + y*img->bytes_per_line);
  297.         while (newp[xs] == oldp[xs]) {
  298.             if (xs == xe)
  299.             return;
  300.             xs++;
  301.         }
  302.         while (newp[xe] == oldp[xe]) xe--;
  303.  
  304.         dst = (char *)(oldp + xs); src = (char *)(newp + xs);
  305.         }
  306.         break;
  307.      case 1:
  308.         {
  309.         uae_u8 *newp = (uae_u8 *)linebuf;
  310.         uae_u8 *oldp = (uae_u8 *)((uae_u8 *)image_mem + y*img->bytes_per_line);
  311.         while (newp[xs] == oldp[xs]) {
  312.             if (xs == xe)
  313.             return;
  314.             xs++;
  315.         }
  316.         while (newp[xe] == oldp[xe]) xe--;
  317.  
  318.         dst = (char *)(oldp + xs); src = (char *)(newp + xs);
  319.         }
  320.         break;
  321.  
  322.      default:
  323.         abort();
  324.         break;
  325.     }
  326.  
  327.     len = xe - xs + 1;
  328.     memcpy (dst, src, len * gfxvidinfo.pixbytes);
  329.     } else if (need_dither) {
  330.     uae_u8 *target = (uae_u8 *)image_mem + img->bytes_per_line * y;
  331.     len = currprefs.gfx_width;
  332.     DitherLine(target, (uae_u16 *)linebuf, 0, y, gfxvidinfo.width, bit_unit);
  333.     } else {
  334.     fprintf(stderr, "Bug!\n");
  335.     abort();
  336.     }
  337.  
  338.     DO_PUTIMAGE (img, xs, y, xs, y, len, 1);
  339. #endif
  340. }
  341.  
  342. void flush_block (int ystart, int ystop)
  343. {
  344. #ifdef USE_DGA_EXTENSION
  345. #else
  346.     int len, xs = 0;
  347.  
  348.     len = gfxvidinfo.width;
  349.     DO_PUTIMAGE (img, xs, ystart, 0, ystart, len, ystop - ystart + 1);
  350. #endif
  351. }
  352.  
  353. void flush_screen (int ystart, int ystop)
  354. {
  355. #ifdef USE_DGA_EXTENSION
  356. #else
  357. #if SHM_SUPPORT_LINKS == 1
  358.     if (currprefs.use_mitshm) XSync(display, 0);
  359. #endif
  360. #endif
  361. }
  362.  
  363. static __inline__ int bitsInMask(unsigned long mask)
  364. {
  365.     /* count bits in mask */
  366.     int n = 0;
  367.     while(mask) {
  368.     n += mask&1;
  369.     mask >>= 1;
  370.     }
  371.     return n;
  372. }
  373.  
  374. static __inline__ int maskShift(unsigned long mask)
  375. {
  376.     /* determine how far mask is shifted */
  377.     int n = 0;
  378.     while(!(mask&1)) {
  379.     n++;
  380.     mask >>= 1;
  381.     }
  382.     return n;
  383. }
  384.  
  385. static unsigned long pixel_return[256];
  386. static XColor parsed_xcolors[256];
  387. static int ncolors = 0;
  388.  
  389. static int blackval = 32767;
  390. static int whiteval = 0;
  391.  
  392. static int get_color(int r, int g, int b, xcolnr *cnp)
  393. {
  394.     XColor *col = parsed_xcolors + ncolors;
  395.     char str[10];
  396.  
  397.     sprintf(str, "rgb:%x/%x/%x", r, g, b);
  398.     XParseColor(display, cmap, str, col);
  399.     *cnp = col->pixel = pixel_return[ncolors];
  400.     XStoreColor (display, cmap, col);
  401.  
  402.     if (r + g + b < blackval)
  403.     blackval = r + g + b, black = *col;
  404.     if (r + g + b > whiteval)
  405.     whiteval = r + g + b, white = *col;
  406.  
  407.     ncolors++;
  408.     return 1;
  409. }
  410.  
  411. static int init_colors(void)
  412. {
  413.     int i;
  414.  
  415.     if (need_dither) {
  416.     if (bitdepth == 1)
  417.         setup_greydither (1, get_color);
  418.     else
  419.         setup_dither (bitdepth, get_color);
  420.     } else {
  421.     if (bitdepth != 8 && bitdepth != 12 && bitdepth != 15
  422.         && bitdepth != 16 && bitdepth != 24) {
  423.         fprintf(stderr, "Unsupported bit depth (%d)\n", bitdepth);
  424.         return 0;
  425.     }
  426.  
  427. #ifdef __cplusplus
  428.     switch(visualInfo.c_class)
  429. #else
  430.     switch(visualInfo.class)
  431. #endif
  432.     {
  433.      case TrueColor:
  434.         {
  435.         int red_bits = bitsInMask(visualInfo.red_mask);
  436.         int green_bits = bitsInMask(visualInfo.green_mask);
  437.         int blue_bits = bitsInMask(visualInfo.blue_mask);
  438.         int red_shift = maskShift(visualInfo.red_mask);
  439.         int green_shift = maskShift(visualInfo.green_mask);
  440.         int blue_shift = maskShift(visualInfo.blue_mask);
  441.         alloc_colors64k(red_bits, green_bits, blue_bits, red_shift,
  442.                 green_shift, blue_shift);
  443.         }
  444.         XParseColor(display, cmap, "#000000", &black);
  445.         if (!XAllocColor(display, cmap, &black))
  446.         fprintf(stderr, "Whoops??\n");
  447.         XParseColor(display, cmap, "#ffffff", &white);
  448.         if (!XAllocColor(display, cmap, &white))
  449.         fprintf(stderr, "Whoops??\n");
  450.         break;
  451.  
  452.      case GrayScale:
  453.      case PseudoColor:
  454.         XAllocColorCells (display, cmap, 0, 0, 0, pixel_return, 256);
  455.         alloc_colors256(get_color);
  456.         break;
  457.  
  458.      default:
  459. #ifdef __cplusplus
  460.         fprintf(stderr, "Unsupported visual class (%d)\n", visualInfo.c_class);
  461. #else
  462.         fprintf(stderr, "Unsupported visual class (%d)\n", visualInfo.class);
  463. #endif
  464.         return 0;
  465.     }
  466.     }
  467.     switch (gfxvidinfo.pixbytes) {
  468.      case 2:
  469.     for (i = 0; i < 4096; i++)
  470.         xcolors[i] = xcolors[i] * 0x00010001;
  471.     gfxvidinfo.can_double = 1;
  472.     break;
  473.      case 1:
  474.     for (i = 0; i < 4096; i++)
  475.         xcolors[i] = xcolors[i] * 0x01010101;
  476.     gfxvidinfo.can_double = 1;
  477.     break;
  478.      default:
  479.     gfxvidinfo.can_double = 0;
  480.     break;
  481.     }
  482.     if(inverse_byte_order)
  483.     switch(gfxvidinfo.pixbytes) {
  484.      case 4:
  485.         for(i = 0; i < 4096; i++)
  486.         xcolors[i] = ((((xcolors[i]>>0)&255) << 24)
  487.                   | (((xcolors[i]>>8)&255) << 16)
  488.                   | (((xcolors[i]>>16)&255) << 8)
  489.                   | (((xcolors[i]>>24)&255) << 0));
  490.         break;
  491.      case 2:
  492.         for (i = 0; i < 4096; i++)
  493.         xcolors[i] = (xcolors[i]>>8) | ((xcolors[i]&255)<<8);
  494.         break;
  495.      default:
  496.         break;
  497.     }
  498.     return 1;
  499. }
  500.  
  501. int graphics_setup(void)
  502. {
  503.     char *display_name = 0;
  504. #ifdef USE_DGA_EXTENSION
  505.     int MajorVersion, MinorVersion;
  506.     int EventBase, ErrorBase;
  507.     if (geteuid()) {
  508.     fprintf(stderr, "You must be root to use UAE with the DGA extensions.\n");
  509.     return 0;
  510.     }
  511. #endif
  512.  
  513.     display = XOpenDisplay(display_name);
  514.     if (display == 0)  {
  515.     fprintf(stderr, "Can't connect to X server %s\n", XDisplayName(display_name));
  516.     return 0;
  517.     }
  518.  
  519. #ifdef USE_DGA_EXTENSION
  520.     if (!XF86DGAQueryVersion (display, &MajorVersion, &MinorVersion)) {
  521.     fprintf(stderr, "Unable to query video extension version\n");
  522.     return 0;
  523.     }
  524.  
  525.     if (!XF86DGAQueryExtension (display, &EventBase, &ErrorBase)) {
  526.     fprintf(stderr, "Unable to query video extension information\n");
  527.     return 0;
  528.     }
  529.  
  530.     /* Fail if the extension version in the server is too old */
  531.     if (MajorVersion < DGA_MINMAJOR ||
  532.     (MajorVersion == DGA_MINMAJOR && MinorVersion < DGA_MINMINOR)) {
  533.     fprintf (stderr,
  534.          "Xserver is running an old XFree86-DGA version"
  535.          " (%d.%d)\n", MajorVersion, MinorVersion);
  536.     fprintf (stderr, "Minimum required version is %d.%d\n",
  537.         DGA_MINMAJOR, DGA_MINMINOR);
  538.     return 0;
  539.     }
  540. #ifdef USE_VIDMODE_EXTENSION
  541.     if (!XF86VidModeQueryVersion (display, &MajorVersion, &MinorVersion)) {
  542.     fprintf (stderr, "Unable to query video extension version\n");
  543.     return 0;
  544.     }
  545.  
  546.     if (!XF86VidModeQueryExtension (display, &EventBase, &ErrorBase)) {
  547.     fprintf (stderr, "Unable to query video extension information\n");
  548.     return 0;
  549.     }
  550.  
  551.     /* Fail if the extension version in the server is too old */
  552.     if (MajorVersion < VidMode_MINMAJOR ||
  553.     (MajorVersion == VidMode_MINMAJOR && MinorVersion < VidMode_MINMINOR)) {
  554.     fprintf (stderr,
  555.          "Xserver is running an old XFree86-VidMode version"
  556.          " (%d.%d)\n", MajorVersion, MinorVersion);
  557.     fprintf (stderr, "Minimum required version is %d.%d\n",
  558.          VidMode_MINMAJOR, VidMode_MINMINOR);
  559.     return 0;
  560.     }
  561.     if (!get_vidmodes ()) {
  562.     fprintf (stderr, "Error getting video mode information\n");
  563.     return 0;
  564.     }
  565. #endif
  566.     
  567. #endif
  568.  
  569.     {
  570.     int local_byte_order;
  571.     int x = 0x04030201;
  572.     char *y=(char*)&x;
  573.  
  574.     local_byte_order = y[0] == 0x04 ? MSBFirst : LSBFirst;
  575.     if (ImageByteOrder(display) != local_byte_order)
  576.         inverse_byte_order = 1;
  577.     }
  578.  
  579.     return 1;
  580. }
  581.  
  582. static void fixup_prefs_dimensions (void)
  583. {
  584.     if (currprefs.gfx_width < 320)
  585.     currprefs.gfx_width = 320;
  586.     if (currprefs.gfx_height < 200)
  587.     currprefs.gfx_height = 200;
  588.     if (currprefs.gfx_height > 300 && ! currprefs.gfx_linedbl)
  589.     currprefs.gfx_height = 300;
  590.     if (currprefs.gfx_height > 600)
  591.     currprefs.gfx_height = 600;
  592.  
  593.     currprefs.gfx_width += 7; /* X86.S wants multiples of 4 bytes, might be 8 in the future. */
  594.     currprefs.gfx_width &= ~7;
  595. }
  596.  
  597. int graphics_init(void)
  598. {
  599.     int i,j;
  600.     XSetWindowAttributes wattr;
  601.     XPixmapFormatValues *xpfvs;
  602.  
  603.     if (currprefs.color_mode > 5)
  604.     fprintf(stderr, "Bad color mode selected. Using default.\n"), currprefs.color_mode = 0;
  605.  
  606.     x11_init_ok = 0;
  607.     need_dither = 0;
  608.     screen_is_picasso = 0;
  609.  
  610.     screen = XDefaultScreen(display);
  611.     rootwin = XRootWindow(display,screen);
  612.  
  613.     /* try for a 12 bit visual first, then a 16 bit, then a 24 bit, then 8 bit */
  614.     if (XMatchVisualInfo(display, screen, 12, TrueColor, &visualInfo)) {
  615.     } else if (XMatchVisualInfo(display, screen, 15, TrueColor, &visualInfo)) {
  616.     } else if (XMatchVisualInfo(display, screen, 16, TrueColor, &visualInfo)) {
  617.     } else if (XMatchVisualInfo(display, screen, 24, TrueColor, &visualInfo)) {
  618.     } else if (XMatchVisualInfo(display, screen, 8, PseudoColor, &visualInfo)) {
  619.     /* for our HP boxes */
  620.     } else if (XMatchVisualInfo(display, screen, 8, GrayScale, &visualInfo)) {
  621.     } else if (XMatchVisualInfo(display, screen, 4, PseudoColor, &visualInfo)) {
  622.     /* VGA16 server. Argh. */
  623.     } else if (XMatchVisualInfo(display, screen, 1, StaticGray, &visualInfo)) {
  624.     /* Mono server. Yuk */
  625.     } else {
  626.     fprintf(stderr, "Can't obtain appropriate X visual.\n");
  627.     return 0;
  628.     }
  629.     vis = visualInfo.visual;
  630.     bitdepth = visualInfo.depth;
  631.  
  632.     /* We now have the bitdepth of the display, but that doesn't tell us yet
  633.      * how many bits to use per pixel. The VGA16 server has a bitdepth of 4,
  634.      * but uses 1 byte per pixel. */
  635.     xpfvs = XListPixmapFormats(display, &i);
  636.     for (j = 0; j < i && xpfvs->depth != bitdepth; j++, xpfvs++)
  637.     ;
  638.     if (j == i) {
  639.     fprintf(stderr, "Your X server is feeling ill.\n");
  640.     return 0;
  641.     }
  642.  
  643.     bit_unit = xpfvs->bits_per_pixel;
  644.     fprintf(stderr, "Using %d bit visual, %d bits per pixel\n", bitdepth, bit_unit);
  645.  
  646.     fixup_prefs_dimensions ();
  647.  
  648.     gfxvidinfo.width = currprefs.gfx_width;
  649.     gfxvidinfo.height = currprefs.gfx_height;
  650.  
  651.     cmap = XCreateColormap(display, rootwin, vis, AllocNone);
  652.  
  653. #ifdef USE_DGA_EXTENSION
  654.     wattr.override_redirect = 1;
  655. #endif
  656.     wattr.event_mask = eventmask;
  657.     wattr.background_pixel = /*black.pixel*/0;
  658.     wattr.backing_store = Always;
  659.     wattr.backing_planes = bitdepth;
  660.     wattr.border_pixmap = None;
  661.     wattr.border_pixel = /*black.pixel*/0;
  662.     wattr.colormap = cmap;
  663.  
  664.     mywin = XCreateWindow(display, rootwin, 0, 0, currprefs.gfx_width, currprefs.gfx_height, 0,
  665.               bitdepth, InputOutput, vis,
  666.               CWEventMask|CWBackPixel|CWBorderPixel|CWBackingStore
  667.               |CWBackingPlanes|CWColormap
  668. #ifdef USE_DGA_EXTENSION
  669.               |CWOverrideRedirect
  670. #endif
  671.               ,&wattr);
  672.  
  673.     current_width = currprefs.gfx_width;
  674.     current_height = currprefs.gfx_height;
  675.  
  676.     XMapWindow(display, mywin);
  677. #ifdef USE_DGA_EXTENSION
  678.     XRaiseWindow(display, mywin);
  679. #else
  680.     XStoreName(display, mywin, "UAE");
  681. #endif
  682.  
  683.     if (bitdepth < 8 || (bitdepth == 8 && currprefs.color_mode == 3)) {
  684.     gfxvidinfo.pixbytes = 2;
  685.     currprefs.use_low_bandwidth = 0;
  686.     need_dither = 1;
  687.     } else {
  688.     gfxvidinfo.pixbytes = bit_unit >> 3;
  689.     }
  690.  
  691. #ifdef USE_DGA_EXTENSION
  692.     enter_dga_mode ();
  693.     /*setuid(getuid());*/
  694. #else
  695.  
  696.     img = get_image (currprefs.gfx_width, currprefs.gfx_height);
  697. #endif
  698.  
  699.     if (need_dither) {
  700.     gfxvidinfo.maxblocklines = 0;
  701.     gfxvidinfo.rowbytes = gfxvidinfo.pixbytes * currprefs.gfx_width;
  702.     gfxvidinfo.linemem = (char *)malloc(gfxvidinfo.rowbytes);
  703.     } else if (currprefs.use_low_bandwidth) {
  704.     gfxvidinfo.maxblocklines = 0;
  705.     gfxvidinfo.rowbytes = img->bytes_per_line;
  706.     gfxvidinfo.linemem = gfxvidinfo.bufmem = (char *)malloc(gfxvidinfo.rowbytes);
  707.     } else {
  708.     gfxvidinfo.maxblocklines = 100; /* whatever... */
  709. #ifndef USE_DGA_EXTENSION
  710.     gfxvidinfo.rowbytes = img->bytes_per_line;
  711.     gfxvidinfo.bufmem = image_mem;
  712. #endif
  713.     gfxvidinfo.linemem = NULL;
  714.     }
  715.  
  716.     if (!init_colors())
  717.     return 0;
  718.  
  719. #ifndef USE_DGA_EXTENSION
  720.     blankCursor = XCreatePixmapCursor(display,
  721.                       XCreatePixmap(display, mywin, 1, 1, 1),
  722.                       XCreatePixmap(display, mywin, 1, 1, 1),
  723.                       &black, &white, 0, 0);
  724.     xhairCursor = XCreateFontCursor(display, XC_crosshair);
  725.  
  726.     whitegc = XCreateGC(display,mywin,0,0);
  727.     blackgc = XCreateGC(display,mywin,0,0);
  728.     picassogc = XCreateGC (display,mywin,0,0);
  729.  
  730.     XSetForeground(display, blackgc, black.pixel);
  731.     XSetForeground(display, whitegc, white.pixel);
  732. #endif
  733.  
  734.     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
  735.     for(i=0; i<256; i++)
  736.     keystate[i] = 0;
  737.  
  738.     lastmx = lastmy = 0;
  739.     newmousecounters = 0;
  740.     inwindow = 0;
  741.  
  742. #ifndef USE_DGA_EXTENSION
  743.     if (!currprefs.no_xhair)
  744.     XDefineCursor(display, mywin, xhairCursor);
  745.     else
  746.     XDefineCursor(display, mywin, blankCursor);
  747.     cursorOn = 1;
  748. #else
  749.     XF86DGAInstallColormap (display, screen, cmap);
  750. #endif
  751.  
  752.     return x11_init_ok = 1;
  753. }
  754.  
  755. void graphics_leave(void)
  756. {
  757.     if (!x11_init_ok)
  758.     return;
  759.  
  760.     if (autorepeatoff)
  761.     XAutoRepeatOn(display);
  762.     XFlush(display);
  763.     XSync(display, 0);
  764. #ifdef USE_DGA_EXTENSION
  765.     leave_dga_mode ();
  766.     dumpcustom();
  767. #endif
  768. }
  769.  
  770. /* Decode KeySyms. This function knows about all keys that are common
  771.  * between different keyboard languages. */
  772. static int kc_decode (KeySym ks)
  773. {
  774.     switch (ks) {
  775.      case XK_B: case XK_b: return AK_B;
  776.      case XK_C: case XK_c: return AK_C;
  777.      case XK_D: case XK_d: return AK_D;
  778.      case XK_E: case XK_e: return AK_E;
  779.      case XK_F: case XK_f: return AK_F;
  780.      case XK_G: case XK_g: return AK_G;
  781.      case XK_H: case XK_h: return AK_H;
  782.      case XK_I: case XK_i: return AK_I;
  783.      case XK_J: case XK_j: return AK_J;
  784.      case XK_K: case XK_k: return AK_K;
  785.      case XK_L: case XK_l: return AK_L;
  786.      case XK_N: case XK_n: return AK_N;
  787.      case XK_O: case XK_o: return AK_O;
  788.      case XK_P: case XK_p: return AK_P;
  789.      case XK_R: case XK_r: return AK_R;
  790.      case XK_S: case XK_s: return AK_S;
  791.      case XK_T: case XK_t: return AK_T;
  792.      case XK_U: case XK_u: return AK_U;
  793.      case XK_V: case XK_v: return AK_V;
  794.      case XK_X: case XK_x: return AK_X;
  795.  
  796.      case XK_0: return AK_0;
  797.      case XK_1: return AK_1;
  798.      case XK_2: return AK_2;
  799.      case XK_3: return AK_3;
  800.      case XK_4: return AK_4;
  801.      case XK_5: return AK_5;
  802.      case XK_6: return AK_6;
  803.      case XK_7: return AK_7;
  804.      case XK_8: return AK_8;
  805.      case XK_9: return AK_9;
  806.  
  807.     /* You never know which Keysyms might be missing on some workstation
  808.      * This #ifdef should be enough. */
  809. #if defined(XK_KP_Prior) && defined(XK_KP_Left) && defined(XK_KP_Insert) && defined (XK_KP_End)
  810.      case XK_KP_0: case XK_KP_Insert: return AK_NP0;
  811.      case XK_KP_1: case XK_KP_End: return AK_NP1;
  812.      case XK_KP_2: case XK_KP_Down: return AK_NP2;
  813.      case XK_KP_3: case XK_KP_Next: return AK_NP3;
  814.      case XK_KP_4: case XK_KP_Left: return AK_NP4;
  815.      case XK_KP_5: case XK_KP_Begin: return AK_NP5;
  816.      case XK_KP_6: case XK_KP_Right: return AK_NP6;
  817.      case XK_KP_7: case XK_KP_Home: return AK_NP7;
  818.      case XK_KP_8: case XK_KP_Up: return AK_NP8;
  819.      case XK_KP_9: case XK_KP_Prior: return AK_NP9;
  820. #else
  821.      case XK_KP_0: return AK_NP0;
  822.      case XK_KP_1: return AK_NP1;
  823.      case XK_KP_2: return AK_NP2;
  824.      case XK_KP_3: return AK_NP3;
  825.      case XK_KP_4: return AK_NP4;
  826.      case XK_KP_5: return AK_NP5;
  827.      case XK_KP_6: return AK_NP6;
  828.      case XK_KP_7: return AK_NP7;
  829.      case XK_KP_8: return AK_NP8;
  830.      case XK_KP_9: return AK_NP9;
  831. #endif
  832.      case XK_KP_Divide: return AK_NPDIV;
  833.      case XK_KP_Multiply: return AK_NPMUL;
  834.      case XK_KP_Subtract: return AK_NPSUB;
  835.      case XK_KP_Add: return AK_NPADD;
  836.      case XK_KP_Decimal: return AK_NPDEL;
  837.      case XK_KP_Enter: return AK_ENT;
  838.  
  839.      case XK_F1: return AK_F1;
  840.      case XK_F2: return AK_F2;
  841.      case XK_F3: return AK_F3;
  842.      case XK_F4: return AK_F4;
  843.      case XK_F5: return AK_F5;
  844.      case XK_F6: return AK_F6;
  845.      case XK_F7: return AK_F7;
  846.      case XK_F8: return AK_F8;
  847.      case XK_F9: return AK_F9;
  848.      case XK_F10: return AK_F10;
  849.  
  850.      case XK_BackSpace: return AK_BS;
  851.      case XK_Delete: return AK_DEL;
  852.      case XK_Control_L: return AK_CTRL;
  853.      case XK_Control_R: return AK_RCTRL;
  854.      case XK_Tab: return AK_TAB;
  855.      case XK_Alt_L: return AK_LALT;
  856.      case XK_Alt_R: return AK_RALT;
  857.      case XK_Meta_R: case XK_Hyper_R: return AK_RAMI;
  858.      case XK_Meta_L: case XK_Hyper_L: return AK_LAMI;
  859.      case XK_Return: return AK_RET;
  860.      case XK_space: return AK_SPC;
  861.      case XK_Shift_L: return AK_LSH;
  862.      case XK_Shift_R: return AK_RSH;
  863.      case XK_Escape: return AK_ESC;
  864.  
  865.      case XK_Insert: return AK_HELP;
  866.      case XK_Home: return AK_NPLPAREN;
  867.      case XK_End: return AK_NPRPAREN;
  868.      case XK_Caps_Lock: return AK_CAPSLOCK;
  869.  
  870.      case XK_Up: return AK_UP;
  871.      case XK_Down: return AK_DN;
  872.      case XK_Left: return AK_LF;
  873.      case XK_Right: return AK_RT;
  874.  
  875.      case XK_F11: return AK_BACKSLASH;
  876. #ifdef USE_DGA_EXTENSION
  877.      case XK_F12:
  878.     uae_quit();
  879.     return -1;
  880. #else
  881.      case XK_F12: return AK_mousestuff;
  882. #endif
  883. #ifdef XK_F14
  884.      case XK_F14:
  885. #endif
  886.      case XK_Scroll_Lock: return AK_inhibit;
  887.  
  888. #ifdef XK_Page_Up /* These are missing occasionally */
  889.      case XK_Page_Up: return AK_RAMI;          /* PgUp mapped to right amiga */
  890.      case XK_Page_Down: return AK_LAMI;        /* PgDn mapped to left amiga */
  891. #endif
  892.     }
  893.     return -1;
  894. }
  895.  
  896. static int decode_fr(KeySym ks)
  897. {
  898.     switch(ks) {        /* FR specific */
  899.      case XK_A: case XK_a: return AK_Q;
  900.      case XK_M: case XK_m: return AK_SEMICOLON;
  901.      case XK_Q: case XK_q: return AK_A;
  902.      case XK_Y: case XK_y: return AK_Y;
  903.      case XK_W: case XK_w: return AK_Z;
  904.      case XK_Z: case XK_z: return AK_W;
  905.      case XK_bracketleft: return AK_LBRACKET;
  906.      case XK_bracketright: return AK_RBRACKET;
  907.      case XK_comma: return AK_M;
  908.      case XK_less: case XK_greater: return AK_LTGT;
  909.      case XK_period: return AK_COMMA;
  910.      case XK_parenright: return AK_MINUS;
  911.      case XK_equal: return AK_SLASH;
  912.      case XK_numbersign: return AK_NUMBERSIGN;
  913.      case XK_slash: return AK_PERIOD;
  914.      case XK_minus: return AK_EQUAL;
  915.      case XK_backslash: return AK_BACKSLASH;
  916.     }
  917.  
  918.     return -1;
  919. }
  920.  
  921. static int decode_us(KeySym ks)
  922. {
  923.     switch(ks) {    /* US specific */
  924.      case XK_A: case XK_a: return AK_A;
  925.      case XK_M: case XK_m: return AK_M;
  926.      case XK_Q: case XK_q: return AK_Q;
  927.      case XK_Y: case XK_y: return AK_Y;
  928.      case XK_W: case XK_w: return AK_W;
  929.      case XK_Z: case XK_z: return AK_Z;
  930.      case XK_bracketleft: return AK_LBRACKET;
  931.      case XK_bracketright: return AK_RBRACKET;
  932.      case XK_comma: return AK_COMMA;
  933.      case XK_period: return AK_PERIOD;
  934.      case XK_slash: return AK_SLASH;
  935.      case XK_semicolon: return AK_SEMICOLON;
  936.      case XK_minus: return AK_MINUS;
  937.      case XK_equal: return AK_EQUAL;
  938.     /* this doesn't work: */
  939.      case XK_quoteright: return AK_QUOTE;
  940.      case XK_quoteleft: return AK_BACKQUOTE;
  941.      case XK_backslash: return AK_BACKSLASH;
  942.     }
  943.  
  944.     return -1;
  945. }
  946.  
  947. static int decode_de(KeySym ks)
  948. {
  949.     switch(ks) {
  950.     /* DE specific */
  951.      case XK_A: case XK_a: return AK_A;
  952.      case XK_M: case XK_m: return AK_M;
  953.      case XK_Q: case XK_q: return AK_Q;
  954.      case XK_W: case XK_w: return AK_W;
  955.      case XK_Y: case XK_y: return AK_Z;
  956.      case XK_Z: case XK_z: return AK_Y;
  957.      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
  958.      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
  959.      case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
  960.      case XK_plus: case XK_asterisk: return AK_RBRACKET;
  961.      case XK_comma: return AK_COMMA;
  962.      case XK_period: return AK_PERIOD;
  963.      case XK_less: case XK_greater: return AK_LTGT;
  964.      case XK_numbersign: return AK_NUMBERSIGN;
  965.      case XK_ssharp: return AK_MINUS;
  966.      case XK_apostrophe: return AK_EQUAL;
  967.      case XK_asciicircum: return AK_BACKQUOTE;
  968.      case XK_minus: return AK_SLASH;
  969.     }
  970.  
  971.     return -1;
  972. }
  973.  
  974. static int decode_se(KeySym ks)
  975. {
  976.     switch(ks) {
  977.     /* SE specific */
  978.      case XK_A: case XK_a: return AK_A;
  979.      case XK_M: case XK_m: return AK_M;
  980.      case XK_Q: case XK_q: return AK_Q;
  981.      case XK_W: case XK_w: return AK_W;
  982.      case XK_Y: case XK_y: return AK_Y;
  983.      case XK_Z: case XK_z: return AK_Z;
  984.      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
  985.      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
  986.      case XK_Aring: case XK_aring: return AK_LBRACKET;
  987.      case XK_comma: return AK_COMMA;
  988.      case XK_period: return AK_PERIOD;
  989.      case XK_minus: return AK_SLASH;
  990.      case XK_less: case XK_greater: return AK_LTGT;
  991.      case XK_plus: case XK_question: return AK_EQUAL;
  992.      case XK_at: case XK_onehalf: return AK_BACKQUOTE;
  993.      case XK_asciitilde: case XK_asciicircum: return AK_RBRACKET;
  994.      case XK_backslash: case XK_bar: return AK_MINUS;
  995.  
  996.      case XK_numbersign: return AK_NUMBERSIGN;
  997.     }
  998.  
  999.     return -1;
  1000.  }
  1001.  
  1002. static int decode_it(KeySym ks)
  1003. {
  1004.     switch(ks) {
  1005.     /* IT specific */
  1006.      case XK_A: case XK_a: return AK_A;
  1007.      case XK_M: case XK_m: return AK_M;
  1008.      case XK_Q: case XK_q: return AK_Q;
  1009.      case XK_W: case XK_w: return AK_W;
  1010.      case XK_Y: case XK_y: return AK_Y;
  1011.      case XK_Z: case XK_z: return AK_Z;
  1012.      case XK_Ograve: case XK_ograve: return AK_SEMICOLON;
  1013.      case XK_Agrave: case XK_agrave: return AK_QUOTE;
  1014.      case XK_Egrave: case XK_egrave: return AK_LBRACKET;
  1015.      case XK_plus: case XK_asterisk: return AK_RBRACKET;
  1016.      case XK_comma: return AK_COMMA;
  1017.      case XK_period: return AK_PERIOD;
  1018.      case XK_less: case XK_greater: return AK_LTGT;
  1019.      case XK_backslash: case XK_bar: return AK_BACKQUOTE;
  1020.      case XK_apostrophe: return AK_MINUS;
  1021.      case XK_Igrave: case XK_igrave: return AK_EQUAL;
  1022.      case XK_minus: return AK_SLASH;
  1023.      case XK_numbersign: return AK_NUMBERSIGN;
  1024.     }
  1025.  
  1026.     return -1;
  1027. }
  1028.  
  1029. static int decode_es(KeySym ks)
  1030. {
  1031.     switch(ks) {
  1032.     /* ES specific */
  1033.      case XK_A: case XK_a: return AK_A;
  1034.      case XK_M: case XK_m: return AK_M;
  1035.      case XK_Q: case XK_q: return AK_Q;
  1036.      case XK_W: case XK_w: return AK_W;
  1037.      case XK_Y: case XK_y: return AK_Y;
  1038.      case XK_Z: case XK_z: return AK_Z;
  1039.      case XK_ntilde: case XK_Ntilde: return AK_SEMICOLON;
  1040. #ifdef XK_dead_acute
  1041.      case XK_dead_acute: case XK_dead_diaeresis: return AK_QUOTE;
  1042.      case XK_dead_grave: case XK_dead_circumflex: return AK_LBRACKET;
  1043. #endif
  1044.      case XK_plus: case XK_asterisk: return AK_RBRACKET;
  1045.      case XK_comma: return AK_COMMA;
  1046.      case XK_period: return AK_PERIOD;
  1047.      case XK_less: case XK_greater: return AK_LTGT;
  1048.      case XK_backslash: case XK_bar: return AK_BACKQUOTE;
  1049.      case XK_apostrophe: return AK_MINUS;
  1050.      case XK_Igrave: case XK_igrave: return AK_EQUAL;
  1051.      case XK_minus: return AK_SLASH;
  1052.      case XK_numbersign: return AK_NUMBERSIGN;
  1053.     }
  1054.  
  1055.     return -1;
  1056. }
  1057.  
  1058. static int keycode2amiga(XKeyEvent *event)
  1059. {
  1060.     KeySym ks;
  1061.     int as;
  1062.     int index = 0;
  1063.  
  1064.     do {
  1065.     ks = XLookupKeysym(event, index);
  1066.     as = kc_decode (ks);
  1067.  
  1068.     if (as == -1) {
  1069.         switch(currprefs.keyboard_lang) {
  1070.  
  1071.         case KBD_LANG_FR:
  1072.         as = decode_fr(ks);
  1073.         break;
  1074.  
  1075.         case KBD_LANG_US:
  1076.         as = decode_us(ks);
  1077.         break;
  1078.  
  1079.          case KBD_LANG_DE:
  1080.         as = decode_de(ks);
  1081.         break;
  1082.  
  1083.          case KBD_LANG_SE:
  1084.         as = decode_se(ks);
  1085.         break;
  1086.  
  1087.          case KBD_LANG_IT:
  1088.         as = decode_it(ks);
  1089.         break;
  1090.  
  1091.          case KBD_LANG_ES:
  1092.         as = decode_es(ks);
  1093.         break;
  1094.  
  1095.          default:
  1096.         as = -1;
  1097.         break;
  1098.         }
  1099.     }
  1100.     if(-1 != as)
  1101.         return as;
  1102.     index++;
  1103.     } while (ks != NoSymbol);
  1104.     return -1;
  1105. }
  1106.  
  1107. static struct timeval lastMotionTime;
  1108.  
  1109. static int refresh_necessary = 0;
  1110.  
  1111. void handle_events(void)
  1112. {
  1113.     newmousecounters = 0;
  1114.     gui_handle_events();
  1115.  
  1116.     for (;;) {
  1117.     XEvent event;
  1118. #if 0
  1119.     if (!XCheckMaskEvent(display, eventmask, &event)) break;
  1120. #endif
  1121.     if (!XPending(display)) break;
  1122.     XNextEvent(display, &event);
  1123.  
  1124.     switch(event.type) {
  1125.      case KeyPress: {
  1126.          int kc = keycode2amiga((XKeyEvent *)&event);
  1127.          if (kc == -1) break;
  1128.          switch (kc) {
  1129.           case AK_mousestuff:
  1130.          togglemouse();
  1131.          break;
  1132.  
  1133.           case AK_inhibit:
  1134.          toggle_inhibit_frame (0);
  1135.          break;
  1136.  
  1137.           default:
  1138.          if (!keystate[kc]) {
  1139.              keystate[kc] = 1;
  1140.              record_key (kc << 1);
  1141.          }
  1142.          break;
  1143.          }
  1144.          break;
  1145.      }
  1146.      case KeyRelease: {
  1147.          int kc = keycode2amiga((XKeyEvent *)&event);
  1148.          if (kc == -1) break;
  1149.          keystate[kc] = 0;
  1150.          record_key ((kc << 1) | 1);
  1151.          break;
  1152.      }
  1153.      case ButtonPress:
  1154.         buttonstate[((XButtonEvent *)&event)->button-1] = 1;
  1155.         break;
  1156.      case ButtonRelease:
  1157.         buttonstate[((XButtonEvent *)&event)->button-1] = 0;
  1158.         break;
  1159. #ifndef USE_DGA_EXTENSION
  1160.      case EnterNotify:
  1161.         newmousecounters = 1;
  1162.         lastmx = ((XCrossingEvent *)&event)->x;
  1163.         lastmy = ((XCrossingEvent *)&event)->y;
  1164.         inwindow = 1;
  1165.         break;
  1166.      case LeaveNotify:
  1167.         inwindow = 0;
  1168.         break;
  1169.      case FocusIn:
  1170.         if (!autorepeatoff)
  1171.         XAutoRepeatOff(display);
  1172.         autorepeatoff = 1;
  1173.         break;
  1174.      case FocusOut:
  1175.         if (autorepeatoff)
  1176.         XAutoRepeatOn(display);
  1177.         autorepeatoff = 0;
  1178.         break;
  1179.      case MotionNotify:
  1180.         if (inwindow) {
  1181.         lastmx = ((XMotionEvent *)&event)->x;
  1182.         lastmy = ((XMotionEvent *)&event)->y;
  1183.         if(!cursorOn && !currprefs.no_xhair) {
  1184.             XDefineCursor(display, mywin, xhairCursor);
  1185.             cursorOn = 1;
  1186.         }
  1187.         gettimeofday(&lastMotionTime, NULL);
  1188.         }
  1189.         break;
  1190.      case Expose:
  1191.         refresh_necessary = 1;
  1192.         break;
  1193. #else
  1194.      case MotionNotify:
  1195.         newmousecounters = 0;
  1196.         lastmx += ((XMotionEvent *)&event)->x_root;
  1197.         lastmy += ((XMotionEvent *)&event)->y_root;
  1198. #endif
  1199.     }
  1200.     }
  1201. #if defined PICASSO96 && !defined USE_DGA_EXTENSION
  1202.     if (screen_is_picasso && refresh_necessary) {
  1203.     DO_PUTIMAGE (picasso_img, 0, 0, 0, 0,
  1204.              picasso_vidinfo.width, picasso_vidinfo.height);
  1205.     refresh_necessary = 0;
  1206.     } else if (screen_is_picasso) {
  1207.     int i;
  1208.     int strt = -1, stop = -1;
  1209.     picasso_invalid_lines[picasso_vidinfo.height] = 0;
  1210.     for (i = 0; i < picasso_vidinfo.height + 1; i++) {
  1211.         if (picasso_invalid_lines[i]) {
  1212.         picasso_invalid_lines[i] = 0;
  1213.         if (strt != -1)
  1214.             continue;
  1215.         strt = i;
  1216.         } else {
  1217.         if (strt == -1)
  1218.             continue;
  1219.         DO_PUTIMAGE (picasso_img, 0, strt, 0, strt,
  1220.                  picasso_vidinfo.width, i-strt);
  1221.         strt = -1;
  1222.         }
  1223.     }
  1224.     }
  1225. #endif
  1226.  
  1227. #ifndef USE_DGA_EXTENSION
  1228.     if (!screen_is_picasso && refresh_necessary) {
  1229.     DO_PUTIMAGE (img, 0, 0, 0, 0, currprefs.gfx_width, currprefs.gfx_height);
  1230.     refresh_necessary = 0;
  1231.     }
  1232.     if(cursorOn && !currprefs.no_xhair) {
  1233.     struct timeval now;
  1234.     int diff;
  1235.     gettimeofday(&now, NULL);
  1236.     diff = (now.tv_sec - lastMotionTime.tv_sec) * 1000000 +
  1237.         (now.tv_usec - lastMotionTime.tv_usec);
  1238.     if(diff > 1000000) {
  1239.         XDefineCursor(display, mywin, blankCursor);
  1240.         cursorOn = 0;
  1241.     }
  1242.     }
  1243. #endif
  1244.     /* "Affengriff" */
  1245.     if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
  1246.     uae_reset();
  1247. }
  1248.  
  1249. int debuggable(void)
  1250. {
  1251.     return 1;
  1252. }
  1253.  
  1254. int needmousehack(void)
  1255. {
  1256. #ifdef USE_DGA_EXTENSION
  1257.     return 0;
  1258. #else
  1259.     return 1;
  1260. #endif
  1261. }
  1262.  
  1263. void LED(int on)
  1264. {
  1265. #if 0 /* Maybe that is responsible for the joystick emulation problems on SunOS? */
  1266.     static int last_on = -1;
  1267.     XKeyboardControl control;
  1268.  
  1269.     if (last_on == on) return;
  1270.     last_on = on;
  1271.     control.led = 1; /* implementation defined */
  1272.     control.led_mode = on ? LedModeOn : LedModeOff;
  1273.     XChangeKeyboardControl(display, KBLed | KBLedMode, &control);
  1274. #endif
  1275. }
  1276.  
  1277. void write_log (const char *buf)
  1278. {
  1279.     fprintf (stderr, buf);
  1280. }
  1281.  
  1282. #ifdef PICASSO96
  1283.  
  1284. void DX_Invalidate (int first, int last)
  1285. {
  1286.     do {
  1287.     picasso_invalid_lines[first] = 1;
  1288.     first++;
  1289.     } while (first <= last);
  1290. }
  1291.  
  1292. int DX_BitsPerCannon (void)
  1293. {
  1294.     return 8;
  1295. }
  1296.  
  1297. void DX_SetPalette(int start, int count)
  1298. {
  1299.     if (!screen_is_picasso || picasso_vidinfo.pixbytes != 1)
  1300.     return;
  1301.  
  1302.     while (count-- > 0) {
  1303.     XColor col = parsed_xcolors[start];
  1304.     col.red = picasso96_state.CLUT[start].Red * 0x0101;
  1305.     col.green = picasso96_state.CLUT[start].Green * 0x0101;
  1306.     col.blue = picasso96_state.CLUT[start].Blue * 0x0101;
  1307.     XStoreColor (display, cmap, &col);
  1308.     start++;
  1309.     }
  1310. #ifdef USE_DGA_EXTENSION
  1311.     /* Why the @§$%&/()=?*+~´#!!! doesn´t this work? */
  1312.     XF86DGAInstallColormap(display, screen, cmap);
  1313. #endif
  1314. }
  1315.  
  1316. #define MAX_SCREEN_MODES 11
  1317.  
  1318. static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 320, 640, 640, 640, 800, 1024, 1152, 1280 };
  1319. static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 256, 400, 350, 480, 512, 600, 768, 864, 1024 };
  1320.  
  1321. int DX_FillResolutions (uae_u16 *ppixel_format)
  1322. {
  1323.     Screen *scr = ScreenOfDisplay (display, screen);
  1324.     int i, count = 0;
  1325.     int w = WidthOfScreen (scr);
  1326.     int h = HeightOfScreen (scr);
  1327.     int maxw = 0, maxh = 0;
  1328.  
  1329.     *ppixel_format = (bit_unit == 8 ? RGBFF_CHUNKY
  1330.               : bitdepth == 15 && bit_unit == 16 ? RGBFF_R5G5B5PC
  1331.               : bitdepth == 16 && bit_unit == 16 ? RGBFF_R5G6B5PC
  1332.               : bit_unit == 24 ? RGBFF_B8G8R8
  1333.               : bit_unit == 32 ? RGBFF_B8G8R8A8
  1334.               : 0);
  1335.  
  1336. #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION
  1337.     for (i = 0; i < vidmodecount && i < MAX_PICASSO_MODES ; i++) {
  1338.     DisplayModes[i].res.width = allmodes[i]->hdisplay;
  1339.     DisplayModes[i].res.height = allmodes[i]->vdisplay;
  1340.     DisplayModes[i].depth = bit_unit >> 3;
  1341.     DisplayModes[i].refresh = 75;
  1342.     }
  1343.     count = i;
  1344. #else
  1345.     for (i = 0; i < MAX_SCREEN_MODES && count < MAX_PICASSO_MODES ; i++) {
  1346.     if (x_size_table[i] <= w && y_size_table[i] <= h) {
  1347.         if (x_size_table[i] > maxw)
  1348.         maxw = x_size_table[i];
  1349.         if (y_size_table[i] > maxh)
  1350.         maxh = y_size_table[i];
  1351.         DisplayModes[count].res.width = x_size_table[i];
  1352.         DisplayModes[count].res.height = y_size_table[i];
  1353.         DisplayModes[count].depth = bit_unit >> 3;
  1354.         DisplayModes[count].refresh = 75;
  1355.         count++;
  1356.     }
  1357.     }
  1358. #endif
  1359.  
  1360. #ifndef USE_DGA_EXTENSION
  1361.     picasso_img = get_image (maxw, maxh);
  1362. #endif
  1363.  
  1364.     return count;
  1365. }
  1366.  
  1367. static void set_window_for_picasso (void)
  1368. {
  1369.     if (current_width != picasso_vidinfo.width || current_height != picasso_vidinfo.height) {
  1370.     current_width = picasso_vidinfo.width;
  1371.     current_height = picasso_vidinfo.height;
  1372.     XResizeWindow (display, mywin, picasso_vidinfo.width,
  1373.                picasso_vidinfo.height);
  1374. #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION
  1375.     switch_to_best_mode ();
  1376. #endif
  1377.     }
  1378.     DX_SetPalette (0, 256);
  1379. }
  1380.  
  1381. static void set_window_for_amiga (void)
  1382. {
  1383.     int i;
  1384.  
  1385.     if (current_width != currprefs.gfx_width || current_height != currprefs.gfx_height) {
  1386.     current_width = currprefs.gfx_width;
  1387.     current_height = currprefs.gfx_height;
  1388.     XResizeWindow (display, mywin, currprefs.gfx_width,
  1389.                currprefs.gfx_height);
  1390. #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION
  1391.     switch_to_best_mode ();
  1392. #endif
  1393.     }
  1394.  
  1395.     if (gfxvidinfo.pixbytes == 1)
  1396.     for (i = 0; i < 256; i++)
  1397.         XStoreColor (display, cmap, parsed_xcolors + i);
  1398. #ifdef USE_DGA_EXTENSION
  1399.     /* Why the @§$%&/()=?*+~´#!!! doesn´t this work? */
  1400.     XF86DGAInstallColormap(display, screen, cmap);
  1401. #endif
  1402. }
  1403.  
  1404. void gfx_set_picasso_modeinfo (int w, int h, int depth)
  1405. {
  1406.     picasso_vidinfo.width = w;
  1407.     picasso_vidinfo.height = h;
  1408.     picasso_vidinfo.depth = depth;
  1409.     picasso_vidinfo.pixbytes = gfxvidinfo.pixbytes;
  1410. #ifdef USE_DGA_EXTENSION
  1411.     picasso_vidinfo.rowbytes = fb_width * gfxvidinfo.pixbytes;
  1412. #else
  1413.     picasso_vidinfo.rowbytes = picasso_img->bytes_per_line;
  1414. #endif
  1415.     picasso_vidinfo.extra_mem = 1;
  1416.  
  1417.     if (screen_is_picasso)
  1418.     set_window_for_picasso ();
  1419. }
  1420.  
  1421. void gfx_set_picasso_baseaddr (uaecptr a)
  1422. {
  1423. }
  1424.  
  1425. void gfx_set_picasso_state (int on)
  1426. {
  1427.     if (on == screen_is_picasso)
  1428.     return;
  1429.     screen_is_picasso = on;
  1430.     if (on)
  1431.     set_window_for_picasso ();
  1432.     else
  1433.     set_window_for_amiga ();
  1434. }
  1435.  
  1436. void begindrawing (void)
  1437. {
  1438. }
  1439.  
  1440. void enddrawing (void)
  1441. {
  1442. }
  1443.  
  1444. uae_u8 *lockscr (void)
  1445. {
  1446. #ifdef USE_DGA_EXTENSION
  1447.     return fb_addr;
  1448. #else
  1449.     return picasso_img->data;
  1450. #endif
  1451. }
  1452. void unlockscr (void)
  1453. {
  1454. }
  1455. #endif
  1456.